# Архитектурные валидаторы (validators)

Валидаторы позволяют контролировать код архитектуры на консистеностность и достаточность. Предоставляют возможность
верифицировать ее с внешними источниками и контролировать архитектурные стандарты.

Каждый валидатор имеет свой уникальный, структурированный идентификатор. На основании идентификаторов строится
[дерево](/problems), которое наглядно определяет где обнаружена проблема.

## Простой валидатор

Пример описания простого валидатора:
```yaml
...
rules:
  validators:
    dochub.experts:                                   # Валидатор контролирует заполнение поля expert для компонентов L1
      title: Не указаны эксперты для компонентов      # Название валидатора
      source: >                                       # Источник данных об ошибках. В данном случае JSONata запрос
        ([([
          components.$spread().(                                                /* Сканируем все компоненты */
            $ID := $keys()[0];
              {                                                                 /* Генерируем массив признаков проблем */
                "isComponent": *.entity = "component",                          /* Это компонент */
                "isDocHubL1Domain": $boolean($match($ID, /dochub\.[^\.]*$/)),   /* в домене DocHub L1 */
                "isExpertEmpty":  $not($boolean("" & *.expert)),                /* и поле expert не заполнено */
                "id": $ID
              }
          )        
        ][isDocHubL1Domain and isExpertEmpty and isComponent]).{ /* Отбираем все компоненты где поле 'expert' пустое*/
            "uid": "expert-component-" & id,                                    /* Уникальный идентификатор выявленной ошибки */
            "location": "/architect/components/" & id,                          /* Ссылка на расположение объекта ошибки */
            "correction": "Укажите эксперта по компоненту",                     /* Рекомендации как исправить проблему */
            "description": "Компоненты L1 должены иметь сведения об экспертах."
        }])
...
```

В поле 'source' можно указать идентификатор источника данных ['dataset'](/docs/dochub.datasets). 
В целом, работа валидаторов с источниками аналогичная работе [таблиц](/docs/dochub.tables) с ними. 

Результатом работы валидатора становится массив структур описывающих обнаруженные ошибки. Например:

```JSON
[
  {
    "uid": "expert-component-dochub.front",
    "location": "/components/dochub.front",
    "correction": "Укажите эксперта компонента",
    "description": "Компоненты должены иметь сведения об эксперте. 
      Если необходимо исключить для данного компонента эту информацию,
      укажите идентификатор ошибки в разделе 'exceptions' с описанием причины",
    "cause": "dochub.standards.examples.expert"
  }
]
```

* ***uid*** - Обязательное поле. Уникальный идентификатор ошибки. Важно обеспечить его глобальную уникальность.
* ***title*** - Опциональное поле. Определяет представление отклонения в дереве.
* ***location*** - Опциональное поле. URL с расположением объекта, где выявлена ошибка.
* ***correction*** - Опциональное поле. Краткое пояснение, как исправить ошибку.
* ***description*** - Опциональное поле. Описание причины ошибки.
* ***cause*** - Опциональное поле. Идентификатор или URL документа, на основании которого создан валидатор.

## Валидатор с использованием JSON Schema

Для контроля метамодели больше подходит специализированный словарь, который позволяет аннотировать и проверять 
структуру данных архитектуры. В качестве такого словаря используется [JSON Schema](https://json-schema.org/), 
реализованная NPM пакетом [avj](https://www.npmjs.com/package/ajv).

Пример описания отклонения:
```yaml
    dochub.fields.source:                             # Валидатор контролирует заполнение поля указывающего на исходник для домена DocHub
                                                      # используя для этого JSON schema (https://json-schema.org/)
      title: Не указан файл исходного кода            # Название валидатора
      schema:                                         # JSON Schema
        type: object
        properties:
          source:
            type: string
        required:
        - source
        additionalProperties: true
      source: >                                       # Источник данных об ошибках
        (
          /* Создаем валидатор JSON schema */
          $validator := $jsonschema($self.schema);  /* Схему валидата получаем из контекста отклонения*/
          /* Формируем базу для проверки */
          ([([
            components.$spread().( /* Сканируем все компоненты */
              $ID := $keys()[0];
              {                                                               /* Генерируем массив признаков проблем */
                "isComponent": *.entity = "component",                        /* Это компонент */
                "isDocHubDomain": $boolean($match($ID, /dochub\.front.*/)),   /* в домене DocHub */
                "id": $ID,                                                    /* Запоминаем идентификатор компонента */
                "isvalid": $validator($.*)                                    /* Валидируем компонент по схеме */									
              }
            )        
          ][isDocHubDomain and isComponent and isvalid != true]).isvalid.{    /* Генерируем отклонения по выявленным нарушениям */
            "uid": $.params.missingProperty & "-component-" & %.id,           /* Уникальный идентификатор выявленной ошибки */
            "location": "/architect/components/" & %.id,                      /* Ссылка на расположение объекта ошибки */
            "correction": "Заполните необходимые поля",                       /* Рекомендации как исправить проблему */
            "description": message
          }])
        )
```

Результат работы валидатора аналогичен простому валидатору.


